#include "listview.h"
#include "itemmodel.h"
#include <QXmlStreamReader>
#include <QDebug>

static RegisterElementType r("ListView", ListView());

ListView::ListView()
    :Element()
    ,up_key_(-1)
    ,down_key_(-1)
    ,current_row_(0)
{
    connect(this, &Element::keyEvent, this, &ListView::onKeyEvent);
}

// 每添加一个成员记得在这里进行copy
bool ListView::copyFrom(const Element *e)
{
   const ListView *l = qobject_cast<const ListView*>(e);
   if(!l){
       return false;
   }
   model_ = l->model_;
   current_row_ = l->current_row_;
   head_ = l->head_;
   up_key_ = l->up_key_;
   down_key_ = l->down_key_;

   return Element::copyFrom(l);
}

Element *ListView::clone() const
{
    ListView *lv = new ListView();
    if(!lv->copyFrom(this)){
        delete lv;
        lv = NULL;
    }
    return lv;
}

void ListView::setModel(ItemModel *model)
{
    model_ = QSharedPointer<ItemModel>(model);
}

ItemModel *ListView::model() const
{
    return model_.data();
}

void ListView::setHead(const QString &head)
{
    head_ = head;
}

QString ListView::head() const
{
    return head_;
}

void ListView::nextPage()
{
    int items_in_page = head().isEmpty()?height():height()-1;

    setPage(currentRow() / items_in_page + 1);
}

void ListView::prevPage()
{
    int items_in_page = head().isEmpty()?height():height()-1;

    setPage(currentRow() / items_in_page - 1);
}

int ListView::currentRow() const
{
    return current_row_;
}

void ListView::setCurrentRow(int row)
{
    if(!model_) return;
    int count = model_->count();
    if(row>=count){
        row = count-1;
    }
    if(row<0){
        row = 0;
    }
    current_row_ = row;

    update();

    emit activated(current_row_);
}

int ListView::currentPage() const
{
    return currentRow()/(height() - 1);
}

int ListView::count() const
{
    return model_?model_->count():0;
}

QRect ListView::sizeHint() const
{
    return QRect(rect_.x(), rect_.y(), 20, 9);
}

void ListView::setPage(int page)
{
    int items_in_page = head().isEmpty()?height():height()-1;

    int temp_row = page * items_in_page;
    if(temp_row>=0 && temp_row<count()){
        // increment page and update current row.
        setCurrentRow(temp_row);
    }
}

void ListView::paintEvent()
{
    if(height()==0)
        return;
    QRect lineRect = rect();
    lineRect.setHeight(1);
    int h = height();
    int y = 0;
    int items_in_page = height();
    if(!head().isEmpty()){
        writeText(lineRect, head());
        h--;
        y++;
        items_in_page--;
    }

    const ItemModel *m = model();
    if(!m) return;

    int first_row = items_in_page * currentPage();
    for(int i=0; i<h; ++i){
        lineRect.setY(lineRect.y()+1);
        if(enable()&&first_row+i==currentRow())
            writeText(lineRect, m->data(first_row+i), Color(255,0,0));
        else
            writeText(lineRect, m->data(first_row+i));
    }
}

void ListView::setUpKey(int upKey)
{
    up_key_ = upKey;
}

int ListView::upKey() const
{
    return up_key_;
}

void ListView::setDownKey(int downKey)
{
    down_key_ = downKey;
}

int ListView::downKey() const
{
    return down_key_;
}

void ListView::onKeyEvent(int key, int value)
{
    if(upKey()==key){
        setCurrentRow(currentRow()+1);
    }else if(downKey()==key){
        setCurrentRow(currentRow()-1);
    }else{
        qWarning() << Q_FUNC_INFO << "Unknow key:" << key;
    }
}

QString ListView::getSignalSignature(const QString &name) const
{
    if(name=="activated"){
        return SIGNAL(activated(int));
    }else{
        return Element::getSignalSignature(name);
    }
}
